from pandas import DataFrame
from tools import *
from tools.entity import MyResult


class BuySeller:
    code = None
    data: DataFrame = None
    signals = None
    sid = None  #
    # 总输入,总输出金额
    inputAll = 0
    outputAll = 0
    buyCnt = 0

    holdCnt = 0  # 持有股票数量
    holdCost = 0  # 持有股票成本

    profitRate = None

    def config(self, code, sid, stgName, signals, data):
        self.sid = sid
        self.stgName = stgName
        self.code = code
        self.signals = signals
        self.data = data.set_index('trade_date')

    def execute(self):
        for date, signal in self.signals.items():
            price = self.data.loc[int(date)]['close']
            if signal > 0:
                self.buy(price)
            else:
                self.sell(price)
        self.end()

    def buy(self, price):
        self.buyCnt += 1

    def sell(self, price):
        pass

    # 结算程序处理
    # 总输入输出计算盈利方式: (总投入金额-总获得金额)/总投入金额/购买次数=平均单次购买盈利率-
    #   弊端: 前期价格普遍偏低,前期和后期投入获得金额混在一起计算盈利混会稀释前期盈利效果
    # (推荐)单次计算盈利最后计算平均盈利方式: 求和(单次买入金额-单次卖出金额)/买入次数    #要在sell方法内写单次盈利率计算
    #   弊端: 单次必须全部卖出,才能发挥该策略优势(准确计算平均盈利率)
    def getProfitRate(self):
        if self.profitRate is not None:
            return round(self.profitRate, 3)
        # 关注信号的成功率
        profit = self.outputAll - self.inputAll
        self.profitRate = (0 if self.inputAll == 0 else profit / self.inputAll / self.buyCnt)
        self.profitRate = round(self.profitRate, 3)
        return self.profitRate

    # 结算人工处理
    def end(self):
        # 交割
        self.sell(self.data.iloc[-1]['close'])
        # 记录日志
        myResult = MyResult(sid=self.sid, input=self.inputAll, output=self.outputAll, profit_rate=self.getProfitRate(),
                            trader=self.__class__.__name__, stg=self.stgName)
        tool.log(myResult)
        dbTool.save(myResult)

# 盈利计算方法	//之前是计算的平均每次投入盈利率,需要总盈利率,
# a. 盈利*买的次数/投入总金额
# b. 盈利/投入总金额
#
# 交易序号: 次数 盈利		//设每次投入1000
# 交易1: 2 800	每次赚400	a:80%, b:40%
# 交易2: 8 800	每次赚100	a:80%, b:10%
# 只要在同一个时间区间, 他们的盈利率应该是一样, 但是b盈利计算方法收益就为10%
# 交易次数越频,在*买的次数后虽然盈利会增加, 但是基数投入金额也会相应增加
# 如果是先买再卖,方案a没问题.  但如果是持续买持有到达8000,方案b没问题
